package lex

import (
	"strconv"
	"strings"
	"unsafe"
)

// Token 单词标记 代表一个最小词法单元
type Token struct {
	//属性值
	Value string
	//种别码
	TYPE TokenType
}

// NewToken 创建标记
func NewToken(TYPE TokenType, value string) Token {
	return Token{
		TYPE:  TYPE,
		Value: value,
	}
}

func (t Token) String() string {
	var buf strings.Builder
	buf.Grow(40)
	buf.WriteString("\t{")
	buf.WriteString("type:")
	buf.WriteString(TokenStrMap[t.TYPE])
	if t.TYPE == MoreThanJustTokensWithBrackts {
		buf.WriteString("\n\t{")
		for _, v := range *t.PtrMoreThanJustTokensWithBracktsS().Ptr {
			buf.WriteString(v.String())
			buf.WriteString("\n")
		}
		buf.WriteString("}\n}\n")
		return buf.String()
	}
	buf.WriteString("\t value:")
	buf.WriteString(t.Value)
	buf.WriteString("}")
	return buf.String()
}

// PtrMoreThanJustTokensWithBracktsS 将 [Token] 的Value字段解释为 [MoreThanJustTokensWithBracktsS] 并返回指针
func (t *Token) PtrMoreThanJustTokensWithBracktsS() *MoreThanJustTokensWithBracktsS {
	return (*MoreThanJustTokensWithBracktsS)(unsafe.Pointer(&t.Value))
}

// 一行的单词标记
type Line struct {
	//从开头到结尾的单词标记
	Value []Token
	//行号
	Linenum int
}

// NewLine 创建一行的标记
func NewLine(num int, tk []Token) Line {
	return Line{Linenum: num, Value: tk}
}

func (l Line) String() string {
	var buf strings.Builder
	buf.Grow(len(l.Value))
	buf.WriteString("[")
	buf.WriteString("行数:")
	buf.WriteString(strconv.Itoa(l.Linenum))
	vlen := len(l.Value)
	if vlen == 0 {
		buf.WriteString("空行")
	} else {
		buf.WriteString("\n")
	}
	for i := 0; i < vlen; i++ {
		buf.WriteString(l.Value[i].String())
		if i%2 == 0 {
			buf.WriteString("\n")
		}
	}
	buf.WriteString("]")
	return buf.String()
}

var (
	TokenStrMap = [...]string{
		No:                            "no (没有表示)",
		NAME:                          "name （符号）",
		ASSIGN:                        "assign (赋值)",
		VAR:                           "var (变量声明)",
		FUNC:                          "func (函数声明)",
		ADD:                           "add (加号)",
		SUB:                           "sub (减号)",
		MUL:                           "mul (乘号)",
		DIV:                           "dlv (除号)",
		LBRACE:                        "lbrace (左大括号)",
		RBRACE:                        "rbrace (右大括号)",
		NUMBER:                        "number (数字)",
		FLOAT:                         "float (浮点数)",
		NoEqual:                       "no equal (不相等)",
		Equal:                         "equal (相等)",
		Less:                          "less (小于)",
		Greater:                       "greater (大于)",
		TRUE:                          "true",
		FALSE:                         "false",
		IF:                            "if",
		ELSE:                          "else",
		FOR:                           "for",
		Break:                         "break",
		Continue:                      "continue",
		Struct:                        "struct",
		Interface:                     "interface",
		LEA:                           "lea (取地址)",
		OnlyLEA:                       "onlylea (&)",
		MLCStart:                      "multiline comment start (多行注释开头)", //multiline comment
		MLCEnd:                        "multiline comment end (多行注释结束)",
		MLCIn:                         "multiline comment in (多行注释之间)",
		String:                        "string (字符串)",
		SEMICOLON:                     "semicolon（分号）",
		Return:                        "return (返回)",
		LPAREN:                        "lparen (左小括号)",
		RPAREN:                        "rparen (右小括号)",
		Comma:                         "comma (逗号)",
		GOTO:                          "goto",
		Colon:                         "colon (冒号)",
		Remain:                        "remainder (取余数)",
		Deref:                         "dereference (解引用)",
		OnlyDeref:                     "OnlyDeref (@)",
		Const:                         "const (常量)",
		Inc:                           "Increment (自增)",
		Dec:                           "Decrement (自减)",
		Nil:                           "nil (指针的零值)",
		Package:                       "package (包声明)",
		Switch:                        "switch",
		Case:                          "case",
		Default:                       "default",
		Method:                        "method (方法)",
		AutoFree:                      "autofree (自动释放块)",
		SinLineComments:               "Single-Line Comments (单行注释)",
		AND:                           "AND (位与运算)",
		Or:                            "Or (位或运算)",
		Xor:                           "Xor (异或运算)",
		LogicAND:                      "logic and (逻辑与)",
		LogicOr:                       "logic or (逻辑或)",
		Import:                        "import (导入)",
		Enum:                          "enum (枚举)",
		TokenWithBrackets:             "TokenWithBrackets (带中括号的Token)", //TokenWithBrackets
		MoreThanJustTokensWithBrackts: "MoreThanJustTokensWithBrackts (不止有中括号的Token)",
	}
)

// 标记类型
type TokenType int

const (
	No TokenType = iota
	NAME
	ASSIGN
	VAR
	FUNC
	ADD
	SUB
	MUL
	DIV
	LBRACE
	RBRACE
	NUMBER
	FLOAT
	NoEqual
	Equal
	Less
	Greater
	TRUE
	FALSE
	IF
	ELSE
	FOR
	Break
	Continue
	Struct
	Interface
	LEA
	OnlyLEA
	MLCStart //multiline comment
	MLCEnd
	MLCIn
	String
	SEMICOLON //semicolon分号
	Return
	LPAREN //Left parenthesis
	RPAREN //right parenthesis
	Comma
	GOTO
	Colon
	Remain
	Deref //dereference
	OnlyDeref
	Const
	Inc //Increment
	Dec //Decrement
	Nil
	Package
	Switch
	Case
	Default
	Method
	AutoFree
	SinLineComments //Single-Line Comments
	AND
	Or
	Xor
	LogicAND
	LogicOr
	Import
	Enum
	TokenWithBrackets
	MoreThanJustTokensWithBrackts //More than just tokens with brackets
)

func (t TokenType) String() string {
	return TokenStrMap[t]
}
